enum Scope{GLOBAL, LOCAL}

enum EntryInfoTypeId{ SCALAR, ARR, FUN, PARAM_ARR}

enum FunReturnType {VOID, OTHERS}

public class EntryInfo {
    EntryInfoTypeId id;
    Scope scope;

    EntryInfo(EntryInfoTypeId _id, Scope _scope) {
	id = _id;
	scope = _scope;
    }
    public EntryInfoTypeId getID() {
	return id;
    }
    public Scope getScope(){
	return scope;
    }
}

class VarEntryInfo extends EntryInfo{
    RtlType type;
    VarEntryInfo(EntryInfoTypeId _id, Scope _scope, RtlType _type){
	super(_id, _scope);
	type = _type;
    }
    public RtlType getRtlType(){
	return type;
    }
}


class LocalEntryInfo extends VarEntryInfo{
    public LocalEntryInfo(EntryInfoTypeId _id, RtlType _type) {
	super(_id, Scope.LOCAL, _type);
    }
}

class ParamArrayEntryInfo extends LocalEntryInfo {
    Temp arrayAddr;
    public ParamArrayEntryInfo(RtlType _type, Temp _value){
	super(EntryInfoTypeId.PARAM_ARR, _type);
	arrayAddr = _value;
    } 
    public Temp getAddr(){
	return arrayAddr;
    }
}

class LocalArrayEntryInfo extends LocalEntryInfo{
    int offset;
    int numOfElements;
    int allignedSize;
    public LocalArrayEntryInfo (RtlType _type, int _offset, int _numOfElements, int _allignedSize) {
	super(EntryInfoTypeId.ARR, _type);
	offset = _offset;
	numOfElements = _numOfElements;
	allignedSize = _allignedSize;
    }
    public int getOffset(){
	return offset;
    }
    public int getNumOfElements(){
	return numOfElements;
    }
    public int getSize() {
	return allignedSize;
    }
}
class LocalScalarEntryInfo extends LocalEntryInfo{
    Temp temp;
    public LocalScalarEntryInfo(RtlType _type, Temp _temp) {
	super(EntryInfoTypeId.SCALAR, _type);
	temp = _temp; 
    } 
    public Temp getTemp(){
	return temp;
    }
}


class GlobalEntryInfo extends VarEntryInfo{
    Data label;
    public GlobalEntryInfo(Data _label, EntryInfoTypeId _id, RtlType _type) {
	super(_id, Scope.GLOBAL, _type);
	label = _label;
    }
    public Data getLabel() {
	return label;
    }
}


class GlobalArrayEntryInfo extends GlobalEntryInfo{

    int numOfElements;
    public GlobalArrayEntryInfo (RtlType _type, Data _label, int _numOfElements) {
	super(_label, EntryInfoTypeId.ARR, _type);
	numOfElements = _numOfElements;
    }
    public int getNumOfElements(){
	return numOfElements;
    }
}
class GlobalScalarEntryInfo extends GlobalEntryInfo{
    public GlobalScalarEntryInfo(RtlType _type, Data _label) {
	super(_label, EntryInfoTypeId.SCALAR, _type);
    } 
}

class FuncDecEntryInfo extends EntryInfo{
    String label;
    FunReturnType retType;
    public FuncDecEntryInfo(String _label, FunReturnType _retType){
	super(EntryInfoTypeId.FUN, Scope.GLOBAL);
	label = _label;
	retType = _retType;
    }
    public String getLabel(){
	return label;
    }
    public FunReturnType getRetType(){
	return retType;
    }
}